package com.huaxin.device.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.huaxin.device.dto.ResponseResult;
import com.huaxin.device.dto.request.DeviceDataCollectionWideAddDTO;
import com.huaxin.device.dto.request.DeviceDataCollectionWideQueryByDataTypePageListReqDTO;
import com.huaxin.device.mapper.DeviceDataCollectionWideMapper;
import com.huaxin.device.mapper.ElectricalRoomMapper;
import com.huaxin.device.mapper.EquipmentDataSourceMapper;
import com.huaxin.device.mapping.DeviceDataCollectionWideMapping;
import com.huaxin.device.models.DeviceDataCollectionWide;
import com.huaxin.device.models.ElectricalRoom;
import com.huaxin.device.models.EquipmentDataSource;
import com.huaxin.device.service.DeviceDataCollectionWideService;
import com.huaxin.hxenum.enums.EquipmentDataType;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.openfeign.Targeter;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class DeviceDataCollectionWideServiceImpl extends ServiceImpl<DeviceDataCollectionWideMapper, DeviceDataCollectionWide> implements DeviceDataCollectionWideService {

    private final DeviceDataCollectionWideMapping deviceDataCollectionWideMapping;
    private final DeviceDataCollectionWideMapper mapper;

    private final ElectricalRoomMapper electricalRoomMapper;
    private final EquipmentDataSourceMapper equipmentDataSourceMapper;
    private final Targeter targeter;

    //添加设备数据
    @Override
    public boolean addDeviceData(List<DeviceDataCollectionWideAddDTO> deviceDataCollectionWide, String stationNumber) {
        if (deviceDataCollectionWide == null || deviceDataCollectionWide.isEmpty()) {
            return false;
        }
        //根据站号获取配电房id
        LambdaQueryWrapper<ElectricalRoom> electricalRoomLambdaQueryWrapper = new LambdaQueryWrapper<>();
        electricalRoomLambdaQueryWrapper.eq(ElectricalRoom::getAutoId, stationNumber);
        ElectricalRoom electricalRoom = electricalRoomMapper.selectOne(electricalRoomLambdaQueryWrapper);
        if (electricalRoom == null) {
            log.error("找不到该站号对应的配电房");
            return false;
        }
        List<DeviceDataCollectionWide> list = new ArrayList<>();
        for (DeviceDataCollectionWideAddDTO item : deviceDataCollectionWide) {
            if (item.getStationNumber() == null || item.getStationNumber() <= 0) {
                log.error("站号不能为空");
                return false;
            }
            DeviceDataCollectionWide deviceDataCollectionWideEntity = deviceDataCollectionWideMapping.toDeviceDataCollectionWide(item);
            deviceDataCollectionWideEntity.setStationNumber(electricalRoom.getAutoId());
            deviceDataCollectionWideEntity.setOrgId(electricalRoom.getOrgId());
            deviceDataCollectionWideEntity.setFamilyId(electricalRoom.getFamilyId());
            list.add(deviceDataCollectionWideEntity);
        }
        return this.saveBatch(list);
    }

    //查询设备数据,按时间倒序
    @Override
    public Page<DeviceDataCollectionWide> queryDeviceData(Integer pageNum, Integer pageSize, String deviceId, String stationNumber) {
        Page<DeviceDataCollectionWide> page = new Page<>(pageNum, pageSize);
        LambdaQueryWrapper<DeviceDataCollectionWide> queryWrapper = new LambdaQueryWrapper<>();
        if (StringUtils.isNotBlank(deviceId)) {
            queryWrapper.eq(DeviceDataCollectionWide::getDeviceId, deviceId);
        }
        if (StringUtils.isBlank(stationNumber)) {
            queryWrapper.eq(DeviceDataCollectionWide::getStationNumber, stationNumber);
        }
        queryWrapper.orderByDesc(DeviceDataCollectionWide::getCreatedAt);
        return this.page(page, queryWrapper);
    }

    @Override
    public ResponseResult<IPage<Map<String, Object>>> queryDeviceDataByDataType(DeviceDataCollectionWideQueryByDataTypePageListReqDTO in) {
        if (in == null) {
            return ResponseResult.parameterError(null, "参数不能为空");
        }

        // 查询电力设备关联的采集设备
        LambdaQueryWrapper<EquipmentDataSource> queryDSWrapper = new LambdaQueryWrapper<>();
        queryDSWrapper.eq(EquipmentDataSource::getEquipmentId, in.getEquipmentId());
        List<EquipmentDataSource> equipmentDataSources = equipmentDataSourceMapper.selectList(queryDSWrapper);
        if (equipmentDataSources == null || equipmentDataSources.isEmpty()) {
            return ResponseResult.notFound(null, "该电力设备未关联采集设备");
        }

        List<String> deviceIds = equipmentDataSources.stream().map(EquipmentDataSource::getCollectorId).distinct().toList();
        List<String> dataTypes = equipmentDataSources.stream().map(EquipmentDataSource::getDataType).toList().stream().map(EquipmentDataType::getCode).distinct().toList();

        IPage<Map<String, Object>> page = new Page<>(in.getPageNum(), in.getPageSize());
        IPage<Map<String, Object>> resultPage = mapper.selectByDeviceIdWithColumns(page, deviceIds, dataTypes, in.getOrgId(), in.getFamilyId());
        return ResponseResult.ok(resultPage);
    }

    /**
     * 根据设备ID和指标字段名，获取该字段的最新值。
     * 此方法通过 SQL SELECT 指定具体字段，避免全表查询，提升性能。
     *
     * @param deviceId    设备ID
     * @param metricField 指标字段名 (如 "voltage", "temperature")
     * @return 字段的最新值，如果设备不存在或无数据则返回 null
     * @throws IllegalArgumentException 当参数无效时抛出
     */
    public Object getLatestByDeviceId(Long deviceId, String metricField) {
        // 参数校验
        if (deviceId == null || deviceId <= 0) {
            throw new IllegalArgumentException("设备ID错误: " + deviceId);
        }
        if (!EquipmentDataType.isValid(metricField)) {
            throw new IllegalArgumentException("不支持的指标字段: " + metricField);
        }

        // 使用 QueryWrapper 构建查询
        QueryWrapper<DeviceDataCollectionWide> wrapper = new QueryWrapper<>();

        // 1. 只查询指定的 metricField 和主键/时间戳（用于排序）
        // 注意：这里直接将字段名拼接到 SQL 中。必须确保 metricField 来自可信的枚举，防止SQL注入！
        wrapper.select(metricField, "created_at") // 只选需要的字段
                .eq("device_id", deviceId)
                .orderByDesc("created_at")
                .last("LIMIT 1"); // 确保只取一条

        try {
            // 2. 执行查询，返回一个 Map，其中 key 是列名，value 是值
            List<Map<String, Object>> result = mapper.selectMaps(wrapper);

            if (result == null || result.isEmpty()) {
                return null;
            }

            // 3. 从结果中提取目标字段的值
            Map<String, Object> row = result.get(0);
            return row.get(metricField);

        } catch (Exception e) {
            // 建议记录日志
            log.error("查询设备 {} 的最新数据失败, 字段: {}");
            throw new RuntimeException("获取设备数据失败", e);
        }
    }
}
